/**
 * \file Server.h
 * \brief Display server definitions
 * \author Corey Tabaka
 */

/*
   Copyright 2007 Corey Tabaka

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include <ktypes.h>
#include <HandleMap.h>
#include <Reference.h>
#include <QList.h>

#include <agg_basics.h>
#include <agg_pixfmt_rgba.h>
#include <agg_rendering_buffer.h>
#include <agg_renderer_base.h>

#ifndef __SERVER_H__
#define __SERVER_H__

//#define AGG_GRAY8
//#define AGG_BGR24
//#define AGG_RGB24
#define AGG_BGRA32 
//#define AGG_RGBA32 
//#define AGG_ARGB32 
//#define AGG_ABGR32
//#define AGG_RGB565
//#define AGG_RGB555
#include <pixel_formats.h>

/**
 * Reference types
 */
class Resource;
DEF_REF_TYPE(Resource);

class Cursor;
DEF_REF_TYPE(Cursor);

class Window;
DEF_REF_TYPE(Window);

enum {
	RESOURCE_TYPE_CURSOR=1,
	RESOURCE_TYPE_WINDOW,
	
	NUM_RESOURCE_TYPES,
};

class Resource {
	protected:
	
	int id;
	int type;
	RefResource self;
	
	static HandleMap<RefResource> resources;
	
	Resource(int id, int type);
	
	public:
	
	int getId(void);
	int getType(void);
	
	static void add(RefResource res);
	static void remove(RefResource res);
	static bool contains(int id);
};

class ImageBuffer {
	public:
	
	agg::rendering_buffer buf;
	pixfmt pixf;
	agg::renderer_base<pixfmt> ren;
	
	ImageBuffer(uint8 *buffer, int width, int height, int scan);
	ImageBuffer(ImageBuffer &ib, int x, int y, int width, int height);
	ImageBuffer(ImageBuffer &ib, agg::rect_i box);
	ImageBuffer(const ImageBuffer &ib);
	
	void init(uint8 *buffer, int width, int height, int scan);
	void init(ImageBuffer &ib, int x, int y, int width, int height);
	void init(ImageBuffer &ib, agg::rect_i box);
};

class Cursor : public Resource {
	protected:
	
	ImageBuffer image;
	int hotX, hotY;
	
	public:
	
	Cursor(int id, ImageBuffer &ib, int hx, int hy);
};

enum {
	WINDOW_FLAGS_DECORATED		= 0x0001,
	WINDOW_FLAGS_BLEND			= 0x0002,
	
	WINDOW_FLAGS_DEFAULT		= WINDOW_FLAGS_DECORATED,
};

enum {
	WINDOW_HINTS_KEEP_BACKING	= 0x0001,
	
	WINDOW_HINTS_DEFAULT		= 0x0000,
};

class Window : public Resource {
	protected:
	
	RefWindow parent;
	RefCursor cursor;
	
	int flags;		// window flags
	int hints;		// window hints
	
	int events;		// event mask
	
	agg::rect_i bounds;
	
	QList siblings;
	QList children;
	
	public:
	
	Window(int id, RefWindow parent);
};

class Mouse {
	protected:
	
	int x, y;
	int lastX, lastY;
	
	bool updated;
	
	RefCursor cursor;
	
	public:
	
	Mouse(void);
	
	void move(int dx, int dy);
	void set(int x, int y);
	
	void setCursor(RefCursor c);
};

class Client {
	protected:
	
	int resourceBase;
	int resourceMask;
	
	HandleMap<RefResource> resources;
	
	public:
	
	Client(int rbase, int rmask);
};

#endif
